// @ts-nocheck

import { useRef } from 'react';


class MousePositionUtil {
  res = [];

  // init
  init() {
    this.res = [];
    return this;
  }

  // 象限
  getQuadrant = (mouseToMidpoint) => {
    if (mouseToMidpoint.x >= 0 && mouseToMidpoint.y >= 0) {
      this.res.push(1);
    } else if (mouseToMidpoint.x <= 0 && mouseToMidpoint.y >= 0) {
      this.res.push(2);
    } else if (mouseToMidpoint.x <= 0 && mouseToMidpoint.y <= 0) {
      this.res.push(3);
    } else if (mouseToMidpoint.x >= 0 && mouseToMidpoint.y <= 0) {
      this.res.push(4);
    }
    return this;
  };

  // toString
  toString() {
    return this.res.join('-');
  }

  // 4方向
  getFourDT = (targetTan, mouseTan) => {
    switch (this.res[0]) {
      case 1:
        this.res.push(mouseTan > targetTan ? 'top' : 'right');
        break;
      case 2:
        this.res.push(mouseTan > targetTan ? 'top' : 'left');
        break;
      case 3:
        this.res.push(mouseTan > targetTan ? 'bottom' : 'left');
        break;
      case 4:
        this.res.push(mouseTan > targetTan ? 'bottom' : 'right');
        break;
      default:
        break;
    }
    return this;
  };

  // 位置 external(外部位置距离)
  // eslint-disable-next-line no-unused-vars
  getFourPosition = (external = 5, mouseToMidpoint, currentNode) => {
    switch (this.res[1]) {
      case 'top':
      case 'bottom':
        this.res.push(Math.abs(mouseToMidpoint.y) > currentNode.h / 2 ? 'outside' : 'inside');
        break;
      case 'left':
      case 'right':
        this.res.push(Math.abs(mouseToMidpoint.x) > currentNode.w / 2 ? 'outside' : 'inside');
        break;
      default:
        break;
    }
    return this;
  };

  filterDropArr(plByNodeDropArr) {
    if (!plByNodeDropArr) return;
    // vInside,hInside,lInside,rInside, bInside,tInside
    // vOutside,hOutside,lOutside,rOutside, bOutside,tOutside
    // res-0 1,2,3,4
    // res-1 bottom top left right
    // res-2 inside outside
    // plByNodeDropArr
    const newRes = [...(this.res || [])];
    // 修正内外侧
    const handleOIConversion = () => {
      const insideArr = ['vInside', 'hInside', 'lInside', 'rInside', 'bInside', 'tInside'];
      const onlyInside = plByNodeDropArr.every((dropStr) => insideArr.includes(dropStr));
      if (onlyInside) {
        newRes[2] = 'inside';
        return;
      }
      const outsideArr = ['vOutside', 'hOutside', 'lOutside', 'rOutside', 'bOutside', 'tOutside'];
      const onlyOutside = plByNodeDropArr.every((dropStr) => outsideArr.includes(dropStr));
      if (onlyOutside) {
        newRes[2] = 'outside';
      }
    };
    handleOIConversion();
    // 修正方向
    const handleInsideFn = () => {
      if (newRes[2] !== 'inside') return;
      const outsideArr = ['vOutside', 'hOutside', 'lOutside', 'rOutside', 'bOutside', 'tOutside'];
      // 修正方向 start
      // 内部单方向
      // 仅存在 一个方向 lInside， rInside， bInside，tInside
      const onlyL = plByNodeDropArr.every((dropStr) =>
        ['lInside', ...outsideArr].includes(dropStr)
      );
      if (onlyL) {
        newRes[1] = 'left';
        return;
      }
      const onlyR = plByNodeDropArr.every((dropStr) =>
        ['rInside', ...outsideArr].includes(dropStr)
      );
      if (onlyR) {
        newRes[1] = 'right';
        return;
      }
      const onlyB = plByNodeDropArr.every((dropStr) =>
        ['bInside', ...outsideArr].includes(dropStr)
      );
      if (onlyB) {
        newRes[1] = 'bottom';
        return;
      }
      const onlyT = plByNodeDropArr.every((dropStr) =>
        ['tInside', ...outsideArr].includes(dropStr)
      );
      if (onlyT) {
        newRes[1] = 'top';
        return;
      }

      // 修正方向 start
      // 内部
      // 仅存在 水平 hInside  lInside，rInside，，
      const onlyH = plByNodeDropArr.every((dropStr) =>
        ['hInside', 'lInside', 'rInside', ...outsideArr].includes(dropStr)
      );
      if (onlyH) {
        switch (newRes[0]) {
          case 1:
          case 4:
            newRes[1] = 'right';
            break;
          case 2:
          case 3:
            newRes[1] = 'left';
            break;
          default:
            break;
        }
        return;
      }
      // 仅存在 垂直 vInside  bInside，tInside，，
      const onlyV = plByNodeDropArr.every((dropStr) =>
        ['vInside', 'bInside', 'tInside', ...outsideArr].includes(dropStr)
      );
      if (onlyV) {
        switch (newRes[0]) {
          case 1:
          case 2:
            newRes[1] = 'top';
            break;
          case 3:
          case 4:
            newRes[1] = 'bottom';
            break;
          default:
            break;
        }
      }
      // end
    };
    const handleOutsideFn = () => {
      if (newRes[2] !== 'outside') return;
      const insideArr = ['vInside', 'hInside', 'lInside', 'rInside', 'bInside', 'tInside'];
      // 修正方向 start
      // 内部单方向
      // 仅存在 一个方向 lOutside，rOutside，bOutside，tOutside
      const onlyL = plByNodeDropArr.every((dropStr) =>
        ['lOutside', ...insideArr].includes(dropStr)
      );
      if (onlyL) {
        newRes[1] = 'left';
        return;
      }
      const onlyR = plByNodeDropArr.every((dropStr) =>
        ['rOutside', ...insideArr].includes(dropStr)
      );
      if (onlyR) {
        newRes[1] = 'right';
        return;
      }
      const onlyB = plByNodeDropArr.every((dropStr) =>
        ['bOutside', ...insideArr].includes(dropStr)
      );
      if (onlyB) {
        newRes[1] = 'bottom';
        return;
      }
      const onlyT = plByNodeDropArr.every((dropStr) =>
        ['tOutside', ...insideArr].includes(dropStr)
      );
      if (onlyT) {
        newRes[1] = 'top';
        return;
      }

      // 修正方向 start
      // 内部
      // 仅存在 水平 hInside  lInside，rInside，，
      const onlyH = plByNodeDropArr.every((dropStr) =>
        ['hOutside', 'lOutside', 'rOutside', ...insideArr].includes(dropStr)
      );
      if (onlyH) {
        switch (newRes[0]) {
          case 1:
          case 4:
            newRes[1] = 'right';
            break;
          case 2:
          case 3:
            newRes[1] = 'left';
            break;
          default:
            break;
        }
        return;
      }
      // 仅存在 垂直 vInside  bInside，tInside，，
      const onlyV = plByNodeDropArr.every((dropStr) =>
        ['vOutside', 'bOutside', 'tOutside', ...insideArr].includes(dropStr)
      );
      if (onlyV) {
        switch (newRes[0]) {
          case 1:
          case 2:
            newRes[1] = 'top';
            break;
          case 3:
          case 4:
            newRes[1] = 'bottom';
            break;
          default:
            break;
        }
      }
      // end
    };
    handleInsideFn();
    handleOutsideFn();
    if (newRes[1] && newRes[2]) {
      return newRes;
    }
    return null;
  }
}

export const useCalculation = (currentNode, eP, store) => {
  const mouseToMidpointP = useRef(null);
  const mouPosDataP = useRef(null);
  mouseToMidpointP.current = null;
  mouPosDataP.current = null;

  if (!currentNode.current) {
    return {
      mouPosDataP,
      mouseToMidpointP,
    };
  }
  const dragNode = store.moveOpNode;
  const dropNode = currentNode.current;

  // 矩形的中点坐标
  let curPos = dropNode.dom.current.getBoundingClientRect()
  currentNode.x = curPos.x
  currentNode.y = curPos.y
  currentNode.h = curPos.height
  currentNode.w = curPos.width
  const midpoint = {
    x: curPos.x + curPos.width / 2,
    y: curPos.y + curPos.height / 2,
  };
  mouseToMidpointP.current = {
    x: eP.current.clientX - midpoint.x,
    y: midpoint.y - eP.current.clientY,
    xAbs: Math.abs(eP.current.clientX - midpoint.x),
    yAbs: Math.abs(eP.current.clientY - midpoint.y),
  };
  // 计算原本矩形高比宽的tan
  const targetTan = Math.abs(currentNode.h / 2 / (currentNode.w / 2));
  // 计算鼠标到中点连线y比x的tan
  const mouseTan = Math.abs(mouseToMidpointP.current.y / mouseToMidpointP.current.x);
  // 获取位置信息
  const mousePositionUtil = new MousePositionUtil();

  // 初始话位置信息
  mouPosDataP.current = mousePositionUtil
    .init()
    // 根据中点,计算象限
    .getQuadrant(mouseToMidpointP.current);
  // 四象限计算
  mouPosDataP.current = mouPosDataP.current
    .getFourDT(targetTan, mouseTan)
    .getFourPosition(5, mouseToMidpointP.current, currentNode);
  return { mouPosDataP, mouseToMidpointP };
};
